use crate::public::Rule;
use reqwest::header::{CONTENT_TYPE, HeaderMap};
use sonic_rs::{JsonValueTrait, json};
use std::collections::{HashMap, HashSet};
use std::sync::OnceLock;

pub static TICKER_STEP: OnceLock<HashMap<String, String>> = OnceLock::new();

pub struct Rest;

impl Rule for Rest {
    async fn get_rule(&self) -> HashSet<String> {
        let body = json!({"ProductGroup": "SwapU"}).to_string();
        let headers = HeaderMap::from_iter([
            (
                CONTENT_TYPE,
                "application/json; charset=UTF-8".parse().unwrap(),
            ),
            ("source".parse().unwrap(), "4".parse().unwrap()),
        ]);
        let client = reqwest::Client::new();
        let resp = client
            .post("https://uuapi.rerrkvifj.com/cfd/agg/v1/instrument")
            .body(body)
            .headers(headers)
            .send()
            .await
            .unwrap();

        let body = resp.text().await.unwrap();

        let array = sonic_rs::get_from_str(body.as_str(), &["dataWrapper"])
            .unwrap()
            .into_array_iter()
            .unwrap();

        let mut set = HashSet::new();
        let mut price_step = HashMap::new();

        for symbol in array {
            let obj = symbol.unwrap();

            let state =
                sonic_rs::get_from_str(obj.as_raw_str(), &["futuresInstrumentExtend", "state"])
                    .unwrap()
                    .as_i64()
                    .unwrap();

            let quote = sonic_rs::get_from_str(obj.as_raw_str(), &["instrument"]).unwrap();

            if state != 3 || quote.get("priceCurrency").as_str().unwrap() != "USDT" {
                continue;
            }

            let price_tick = quote.get("priceTick").as_str().unwrap().to_string();

            let symbol = quote.get("instrumentID").as_str().unwrap().to_string();

            price_step.insert(symbol.to_string(), price_tick);

            set.insert(symbol);
        }

        TICKER_STEP.get_or_init(|| price_step);

        set
    }
}
